package pl.un4giv3n.mightvsmagic.action;

import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import pl.un4giv3n.mightvsmagic.entity.Clan;
import pl.un4giv3n.mightvsmagic.entity.User;
import pl.un4giv3n.mightvsmagic.utils.ClanStats;
import pl.un4giv3n.mightvsmagic.utils.ClanStatsUtil;
import pl.un4giv3n.mightvsmagic.utils.StatsUtil;
import pl.un4giv3n.mightvsmagic.utils.UserStats;

/**
 * @author andrzejewskia
 * shows the ranking page
 */
public class RankingPageAction extends PersistenceAction{

	private static final long serialVersionUID = 1L;
	private enum RankType{
		USER,
		CLAN
	}
	/**
	 * all users from the db
	 */
	private List<User> userList;
	private List<Clan> clanList;
	private RankType rankType = RankType.USER;

	@SuppressWarnings("unchecked")
	@Override
	public String execute(){
		EntityManager entityManager = getEntityManager();
		User user = getSessionUser(entityManager);
		if(user == null){
			addActionError("Zaloguj się");
			entityManager.close();
			return LOGIN;
		}
		if(rankType == RankType.USER){
			Query query = entityManager.createNamedQuery("find.all.unblocked.users");
			userList = query.getResultList();
			removeUncachedUsers();
			Collections.sort(userList, new Comparator<User>(){
				public int compare(User o1, User o2) {
					long o1exp = o1.getFightExp() + o1.getMagicExp();
					long o2exp = o2.getFightExp() + o2.getMagicExp();
					return (o1exp<o2exp ? 1 : (o1exp==o2exp ? 0 : -1));
				};
			});
			return "userrank";
		}else{
			Query query = entityManager.createNamedQuery("find.all.clans");
			clanList = query.getResultList();
			removeUncachedClans();
			Collections.sort(clanList, ClanStatsUtil.NAME_COMPARATOR);
			return "clanrank";
		}
	}

	private void removeUncachedClans() {
		Map<Long, ClanStats> cachedStats = ClanStatsUtil.getCachedStats();
		for (Iterator<Clan> iterator = clanList.iterator(); iterator.hasNext();) {
			Clan clan = iterator.next();
			if(!cachedStats.containsKey(clan.getId())){
				iterator.remove();
			}
			
		}
	}

	private void removeUncachedUsers() {
		Map<Long, UserStats> cachedStats = StatsUtil.getCachedStats();
		for (Iterator<User> iterator = userList.iterator(); iterator.hasNext();) {
			User user = iterator.next();
			if(!cachedStats.containsKey(user.getId())){
				iterator.remove();
			}
			
		}
	}

	public List<User> getUserList() {
		return userList;
	}

	public RankType getRankType() {
		return rankType;
	}

	public void setRankType(String rankType) {
		this.rankType = RankType.valueOf(rankType);
	}

	public List<Clan> getClanList() {
		return clanList;
	}
	
}
